package com.huangfu.learning.javabase.java.pattern.structure.proxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * Created with IntelliJ IDEA.
 * Author: huangfu.daohui
 * Date: 2018/7/20
 * Time: 16:00
 * Version: 1.0
 * Description:Cglib代理测试
 * 不需要目标类实现接口，使用目标类子类的方式来实现代理模式，所以有叫做子类代理.
 * 需要引入spring-core的依赖包
 **/
class CglibProxyPractice {
    //测试
    public static void main(String[] args) {

        //目标对象
        CglibTargetUserDao target = new CglibTargetUserDao();
        //代理对象
        CglibTargetUserDao proxy = (CglibTargetUserDao) new CglibProxyFactory(target).getProxyInstence();
        //执行代理对象的方法
//        proxy.save();
        proxy.query("huangfu");
    }
}

//目标类 ，不实现任何接口
class CglibTargetUserDao {
    public void save() {
        System.out.println("Cglib代理 CglibTargetUserDao.save 保存成功！");
    }
    public String query(String name) {
        return "Cglib代理 CglibTargetUserDao.query 查询！";
    }
}

// Cglib 子类工厂，对CglibTargetUserDao在内存中动态构建一个子类对象
public class CglibProxyFactory implements MethodInterceptor {

    //维护目标对象
    private Object target;

    public CglibProxyFactory(Object target) {
        this.target = target;
    }

    //给目标对象创建一个代理对象
    public Object getProxyInstence() {
        //1、工具类
        Enhancer enhancer = new Enhancer();
        //2、设置父类
        enhancer.setSuperclass(target.getClass());
        //3、设置回调函数
        enhancer.setCallback(this);
        //4、创建子类(代理类)
        return enhancer.create();
    }


    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        System.out.println("目标类方法执行之前操作（开启事务、鉴权等）。。。");
        Object returnValue = method.invoke(target, objects);
        System.out.println("目标类方法执行之后操作（提交事务、日志等）。。。");
        return returnValue;
    }
}